/*********************************** (C) COPYRIGHT ******************************
 * address: https://gitee.com/liuniansihuo/multitasks-os
 *
 * Change Logs:
 * Date			Author      	Notes
 * 2017-04-19	LiuHuo			first version
 *
*******************************************************************************/

#define __os_sys_C_
#include  <stdarg.h>
#include "os_sys.h"





static struct task_s sys_task_buff[TASKID_MAX]={{TASKID_SYS}};
static const u32 sys_task_point_default=0;
static const void * sys_task_point_buff[POINT_MAX]={[POINT_NULL]=&sys_task_point_default};

static u8 sys_loop_flag=1;

 /*
* function:任务初始化
*/
static void  sys_task_create_init(void)
{
    E_TASKID id;

    for (id = TASKID_SYS; id < TASKID_MAX; id++) //调用任务初始化函数
    {
        if (sys_task_buff[id].is_used)
        {
            if (NULL != sys_task_buff[id].task_init)
                sys_task_buff[id].task_init();
        }
    }

	for(int i=0; i<POINT_MAX; i++)
	{
		if(NULL == sys_task_point_buff[i])
		{
			while(1);//若没有注册，就死循环，防止引用时因为NULL，导致程序跑飞
		}
	}

}

/*
* function:添加任务
* param：
* return：0：ok    !0:error
*/
unsigned char sys_task_add(const struct task_s * task)
{
	if(task->ID >=TASKID_MAX)
		return 1;
	if(sys_task_buff[task->ID].is_used)
		return 2;

	sys_task_buff[task->ID] = *task;
	sys_task_buff[task->ID].is_used = 1;
	return 0;
}
/*
* function:删除指定任务
* param:
	id:任务ID
* return 0：OK
*/
unsigned char  sys_task_del(E_TASKID id)
{
	unsigned char * buff;
	unsigned int i;

	if(0 == sys_task_buff[id].is_used)
		return 1;

	if(id<TASKID_MAX)
	{
		buff =(unsigned char *)(&sys_task_buff[id]);
		for(i=0; i<sizeof(struct task_s); i++)
			buff[i]=0;
	}
	else if(id==TASKID_MAX)// delet all task
	{
		buff= (unsigned char *)sys_task_buff;
		for(i=0; i < TASKID_MAX*sizeof(struct task_s); i++)
		{
			buff[i]=0;
		}
	}

	return 0;
}
/*
* function:消息处理
* param:
	DatID:消息ID
	data:消息缓存
	id:任务ID
* return:
*/
void  sys_msg_process(E_DATAID DatID,  const u32 data ,E_TASKID id)
{
  	if(id>=TASKID_MAX)
		return;
	if(0 == sys_task_buff[id].is_used)
		return ;
	if(sys_task_buff[id].msg_process != NULL)
	{
		(sys_task_buff[id].msg_process)(DatID,data);
	}
}
/*
* function:消息处理,任务重调用
* param:
	DatID:消息ID
	data:消息缓存
	num:出理消息的任务个数
	...:任务ID列表
* return:
*/
u8 sys_msg_send(E_DATAID DatID,  const u32 data ,u32 num,...)
{
	int i;

	if(num>=TASKID_MAX)
	{
		num=TASKID_MAX;
		for (i = 0; i < num; i++)
		{
			sys_msg_process(DatID, data ,(E_TASKID)i);
		}
	}
	else
	{
		int task_id;
		va_list vl;
		va_start(vl,num);
		for (i = 0; i < (num); i++)
		{
			task_id = va_arg(vl, int);
			sys_msg_process(DatID, data ,(E_TASKID)task_id);
		}
		va_end(vl);
	}
	return 0u;
}
/*
* function: 获取指定任务状态
* param:
	id:任务ID
* return：返回任务状态
*/
task_stat_e sys_task_state_get(E_TASKID id)
{
	if((id>=TASKID_MAX) || (sys_task_buff[id].is_used==0))
		return TASK_STAT_NOT_EXIST;

	return sys_task_buff[id].state;
}
/*
* function: 设置指定任务状态
* param:
	id:任务ID
	state：任务状态
* return：
*/
void sys_task_state_set(E_TASKID id,task_stat_e state)
{
	if((id>=TASKID_MAX) || (sys_task_buff[id].is_used==0))
		return ;

	sys_task_buff[id].state = state;
}
/*
* function: 所有任务运行函数执行
* param:
* return:
*/
static void sys_run(void)
{
	E_TASKID id;

	for(id=TASKID_SYS; id<TASKID_MAX; id++)
	{
		if(sys_task_buff[id].is_used && (NULL != sys_task_buff[id].run))
		{
			sys_task_buff[id].run();
		}
	}
}
/*
* function: 所有任务sleep运行函数执行
* param:
* return:
*/
static void sys_task_sleep_init(void)
{
	E_TASKID id;

	for(id=TASKID_SYS; id<TASKID_MAX; id++)
	{
		if(sys_task_buff[id].is_used && (NULL != sys_task_buff[id].sleep_init))
		{
			sys_task_buff[id].sleep_init();
		}
	}
}
/*
* function: 所有任务tick运行函数执行
* param:
* return:
*/

static void sys_task_tick(void)
{
	E_TASKID id;
	static SysTick_t task_tick=0;
	unsigned int diff=0;

	diff = systick_get_time_difference(task_tick);

	if(diff == 0)
		return ;

	for(id=TASKID_SYS; id<TASKID_MAX; id++)
	{
		if(sys_task_buff[id].is_used)
		{
			if(NULL != sys_task_buff[id].task_tick)
			{
				for(int i=0; i<diff; i++)
					sys_task_buff[id].task_tick();
			}
		}
	}
	task_tick = systick_get_currTime();
}

/*
* function: 设置系统循环标志
* param:
	flag；系统循环标志

* return:
*/
void sys_loop_flag_set(u8 flag)
{
	sys_loop_flag = flag;
}

void sys_main(void)
{
	sys_task_create_init();
	while(sys_loop_flag == 1)
	{
		sys_run();
		sys_task_tick();
	}

	sys_task_sleep_init();;
}
/*
* function: 任务指针的注册与获取
* param:
*	ID：指针在引用数组中的序号
*	p: 任务数据指针
* return:
*/
void sys_task_point_set(E_DATAID ID,const void * const p)
{
	(ID>=POINT_MAX) ? 0: (sys_task_point_buff[ID] = p);
}
const void * sys_task_point_get(E_DATAID ID)
{
	return (ID>=POINT_MAX) ? sys_task_point_buff[POINT_NULL] : sys_task_point_buff[ID];
}

